package com.gmadmin.service.impl;


import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.gmadmin.entity.SysUser;
import com.gmadmin.entity.dto.SysRoleDto;
import com.gmadmin.entity.dto.SysUserDto;
import com.gmadmin.exception.UserException;
import com.gmadmin.mapper.SysUserMapper;
import com.gmadmin.payload.UserQueryCriteria;
import com.gmadmin.service.SysRoleService;
import com.gmadmin.service.UnitOrganizationService;
import com.gmadmin.service.SysUserService;
import com.gmadmin.service.UnitPositionService;
import com.gmadmin.service.dto.UnitOrganizationDto;
import com.gmadmin.service.dto.UnitPositionDto;
import com.gmadmin.service.vo.UnitOrganizationVo;
import com.gmadmin.service.vo.UnitPositionVo;
import com.gmadmin.entity.vo.role.SysRoleVo;
import com.gmadmin.entity.vo.user.SysUserVo;
import com.gmadmin.utils.CollectionBeanUtils;
import com.gmadmin.utils.FileUtils;
import com.gmadmin.vo.PageVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zhangliang
 * @version 1.0
 * @date 2021/2/2 15:31
 */
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {

    protected static final Logger logger = LoggerFactory.getLogger(SysUserServiceImpl.class);

    private final SysRoleService roleService;

    private final UnitOrganizationService organizationService;

    private final UnitPositionService positionService;

    public SysUserServiceImpl(SysRoleService roleService, UnitOrganizationService organizationService, UnitPositionService positionService) {
        this.roleService = roleService;
        this.organizationService = organizationService;
        this.positionService = positionService;
    }

    @Override
    public PageVo<SysUserVo> findListByPage(UserQueryCriteria queryCriteria, Page<SysUser> page) {
        IPage<SysUser> sysUserIPage = baseMapper.findListByPage(queryCriteria, page);
        List<SysUser> users = sysUserIPage.getRecords();


        List<SysUserVo> sysUserVos = CollectionBeanUtils.copyListProperties(users, SysUserVo::new);
        sysUserVos = sysUserVos.stream().peek(sysUserVo -> {

            //            设置角色
            List<SysRoleVo> sysRoleVos = roleService.getByUserId(sysUserVo.getId());
            sysUserVo.setRoles(sysRoleVos);

//            设置部门
            List<UnitOrganizationVo> organizationVos = organizationService.getByUserId(sysUserVo.getId());
            sysUserVo.setOrganizations(organizationVos);

//            设置职位

            List<UnitPositionVo> unitPositionVos = positionService.getByUserId(sysUserVo.getId());
            sysUserVo.setPositions(unitPositionVos);
        }).collect(Collectors.toList());

        PageVo<SysUserVo> pageVo = new PageVo<>(sysUserVos, sysUserIPage.getTotal());
        return pageVo;
    }

    @Override
    public SysUserVo findByUsernameOrEmailOrPhone(String usernameOrEmailOrPhone) {
        SysUser sysUser = baseMapper.findByUsernameOrEmailOrPhone(usernameOrEmailOrPhone).orElse(new SysUser());
        SysUserVo sysUserVo = new SysUserVo();
        BeanUtils.copyProperties(sysUser, sysUserVo);
        return sysUserVo;
    }


    @Transactional(rollbackFor = UserException.class)
    @Override
    public void delUsers(List<Long> userIds) {
//        删除角色用户中间表信息
        baseMapper.deleteUsersAndRoles(userIds);
//        删除用户与job中间表
        baseMapper.deleteUsersAndPositions(userIds);
        baseMapper.deleteBatchIds(userIds);
    }

//    @Transactional(rollbackFor = UserException.class)
//    @Override
//    public boolean updateUserById(SysUser sysUser, List<SysRole> sysRoles, List<SysJob> sysJobs) {
//        if (ObjectUtil.isNotEmpty(baseMapper.updateById(sysUser))) {
//            // 更新角色
//            Long id = sysUser.getUserId();
//            if (ObjectUtil.isNotEmpty(sysRoles)) {
//
//                LogUtil.debug("更新角色");
//                LogUtil.debug(JSONUtil.toJsonStr(id));
//                baseMapper.deleteUser_role(Collections.singletonList(id));
//                for (SysRole role : sysRoles
//                ) {
//                    baseMapper.insertUser_Role(sysUser, role);
//                }
//            }
////           更新职位
//            if (ObjectUtil.isNotEmpty(sysJobs)) {
//
//                baseMapper.deleteUser_job(Collections.singletonList(id));
//                for (SysJob job : sysJobs
//                ) {
//                    baseMapper.insertUser_job(sysUser, job);
//                }
//            }
//            return true;
//        }
//        return false;
//    }


    @Transactional(rollbackFor = UserException.class)
    @Override
    public void saveOrUpdateUser(SysUserDto userDto) {
        SysUser sysUser = new SysUser();
        BeanUtils.copyProperties(userDto, sysUser);
        saveOrUpdate(sysUser);

        if (Objects.nonNull(userDto.getRoles())) {
            List<Long> roleIds = userDto.getRoles().stream().map(SysRoleDto::getId).collect(Collectors.toList());
            deleteAndSaveUserAndRoles(sysUser.getId(), roleIds);
        }
        if (Objects.nonNull(userDto.getOrganizations())) {
            List<Long> organizationIds = userDto.getOrganizations().stream().map(UnitOrganizationDto::getId).collect(Collectors.toList());
            deleteAndSaveUserAndOrganization(sysUser.getId(), organizationIds);
        }
        if (Objects.nonNull(userDto.getPositions())) {
            List<Long> positionIds = userDto.getPositions().stream().map(UnitPositionDto::getId).collect(Collectors.toList());
            deleteAndSaveUserAndPositions(sysUser.getId(), positionIds);

        }
    }


    @Transactional(rollbackFor = UserException.class)
    @Override
    public void delUser(Long id) {
        baseMapper.deleteById(id);
    }

    @Transactional(rollbackFor = UserException.class)
    @Override
    public void deleteAndSaveUserAndPositions(Long userId, List<Long> positionIds) {
        baseMapper.deleteUsersAndPositions(Collections.singletonList(userId));
        if (!positionIds.isEmpty()) baseMapper.insertUserAndPositions(userId, positionIds);

    }

    @Transactional(rollbackFor = UserException.class)
    public void deleteAndSaveUserAndOrganization(Long userId, List<Long> organizationIds) {
        baseMapper.deleteUsersAndOrganizations(Collections.singletonList(userId));
        if (!organizationIds.isEmpty()) baseMapper.insertUserAndOrganizations(userId, organizationIds);
    }


    @Transactional
    @Override
    public void deleteAndSaveUserAndRoles(Long userId, List<Long> roleIds) {
        baseMapper.deleteUsersAndRoles(Collections.singletonList(userId));
        if (!roleIds.isEmpty()) baseMapper.insertUserAndRoles(userId, roleIds);
    }


    @Override
    public void download(HttpServletResponse response, List<Long> ids) throws IOException {

        List<SysUser> sysUsers = baseMapper.findAll(ids);

        List<Map<String, Object>> mapList = new ArrayList<>();

        for (SysUser sysUser : sysUsers) {
            Map<String, Object> map = new LinkedHashMap<>();

            map.put("用户名", sysUser.getUsername());
            map.put("昵称", sysUser.getNickName());
            map.put("性别", sysUser.getGender());
            map.put("电话", sysUser.getPhone());
            map.put("邮箱", sysUser.getEmail());

            map.put("状态", sysUser.getEnabled());

            map.put("创建人", sysUser.getCreateBy());
            map.put("更新人", sysUser.getUpdateBy());
            map.put("创建日期", sysUser.getCreateTime());
            map.put("更新日期", sysUser.getUpdateTime());
            mapList.add(map);
        }


        FileUtils.downloadExcel(mapList, response);
    }
}
